package com.project.springboot.service.miaosha.impl;

import com.gitee.yongzhuzl.commonutil.util.random.RandomUtil;
import com.project.springboot.exception.ResponseException;
import com.project.springboot.service.miaosha.SecondKillService;
import com.project.springboot.utils.MyRedisLock;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * description: 秒杀服务接口实现类
 * @author 朱正磊
 * @date 2021-03-17 15:03:52
 */
@Service
public class SecondKillServiceImpl implements SecondKillService {

    /**
     * 超时时间 10秒
     */
    private static final int TIME_OUT = 10 * 1000;

    /**
     * 商品总库存，key为商品ID，值为商品总库存数
     */
    private static Map<String, Integer> productTotalStock;

    /**
     * 商品剩余库存，key为商品ID，值为商品剩余库存数
     */
    private static Map<String, Integer> productSurplusStock;

    /**
     * 用户商品订单，key为用户ID，值为商品ID
     */
    private static Map<String, String> userProductOrder;

    @Resource
    private MyRedisLock myRedisLock;

    // 国庆活动，苹果手机特价，限量100000台
    // 模拟多张表，商品表，库存表，秒杀成功订单表
    // 使用静态代码块初始化成员变量
    static {
        productTotalStock = new HashMap<>();
        productSurplusStock = new HashMap<>();
        userProductOrder = new HashMap<>();
        productTotalStock.put("iphone_id", 100000);
        productSurplusStock.put("iphone_id", 100000);
    }

    /**
     * description: 查询秒杀商品信息
     * @author 朱正磊
     * @date 2021-03-17 15:02:25
     * @param productId 商品ID
     * @return 返回秒杀商品信息
     */
    @Override
    public String querySecondKillProductInfo(String productId) {
        return "国庆活动，苹果手机特价，限量" + productTotalStock.get(productId) + "台"
                + "，还剩：" + productSurplusStock.get(productId) + "台"
                + "，该商品成功下单用户数目：" + userProductOrder.size() + "人";
    }

    /**
     * description: 模拟多线程秒杀商品
     * @author 朱正磊
     * @date 2021-03-17 15:02:30
     * @param productId 商品ID
     */
    @Override
    public void mockMultithreadingOrderProduct(String productId) {
        // 加锁（锁：当前时间 + 超时时间）
        String lockValue = Long.toString(System.currentTimeMillis() + TIME_OUT);
        // 如果加锁成功返回true，否则返回false
        Boolean isLock = myRedisLock.lock(productId, lockValue);
        if (!isLock) {
            // 如果加锁失败
            throw new ResponseException(101, "哎呦喂，人也太多了吧，请换个姿势再试试~~~");
        }

        // 业务逻辑
        // 查询该商品的剩余库存，如果剩余库存为0则表示该活动已经结束
        // 获取当前商品的剩余库存
        int productSurplusStockNum = productSurplusStock.get(productId);
        if (productSurplusStockNum == 0) {
            // 如果剩余库存为0则表示该活动已经结束
            throw new ResponseException(102, "苹果手机特价活动已结束！");
        } else {
            // 模拟用户下单
            userProductOrder.put(RandomUtil.getUuidNoLine(), productId);
            // 进行减库存操作
            productSurplusStockNum = productSurplusStockNum - 1;
            try {
                // 让线程休眠0.5秒，模拟业务耗时，比如对数据库的持久化操作等等
                Thread.sleep(500L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            productSurplusStock.put(productId, productSurplusStockNum);
        }

        // 解锁
        myRedisLock.unlock(productId, lockValue);
    }

}
